package com.study.reflect.example.ex02;

import java.lang.reflect.Method;
import java.util.ArrayList;

import org.junit.Test;

/**
* @Name: ArrayListDemo
* @Description: 反射练习二：向ArrayList<Integer>集合对象中添加字符串元素
* 分析：
* 	查看ArrayList的源码：
* 		public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
        	public boolean add(E e) {... ...}
        }
          发现： 所谓的ArrayList<Integer>泛型中指定的Integer只是给编译器看的，其实ArrayList的底层还是接收的泛型E，即接收的是一个Object对象
                      无非在添加元素的时候，将添加的数据，转换成整型，如果添加的不是整型数据，在编译时将出现类型转换错误，这只是编译器在进行数据类型的转换，而与ArrayList<E>底层代码并无任何关系。
        	array.add(2) -> array.add(Integer.valueOf(2))
       	因此，我们可以通过泛型获取ArrayList<E>的add()方法，从而向集合中添加字符串，并进行输出。
* @Author: 李超	lc_jack@foxmail.com
* @CreateDate: 2017-1-17 下午7:58:05 
* @Version: V1.0
 */
public class ArrayListDemo {
	
	/**
	* @Name: arrayListTest
	* @Description: ArrayList<E>源码分析
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-1-17 下午8:12:27
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void arrayListTest() {
		//说明：ArrayList<Integer>中的Integer只是写给编译器看的，用来限制检查向集合中添加的必须为整型元素
		ArrayList<Integer> array = new ArrayList<Integer>() ;
		//array.add(2)->array.add(Integer.valueOf(2))，此处进行类型转换，如果添加的数据不是整型数据，将出现类型转换错误；
		//但是，ArrayList<E>的代码并没有发生任何改变，其实际接收的类型依旧为Object类型
		array.add(2) ;  
		System.out.println(array); 
	}
	
	/**
	* @Name: test
	* @Description: 向ArrayList<Integer>集合对象中添加字符串元素
	* @Author: 李超	lc_jack@foxmail.com
	* @Version: V1.0
	* @CreateDate: 2017-1-17 下午8:16:38
	* @Parameters: 
	* @Return: void
	 */
	@Test
	public void test() throws Exception {
		//创建ArrayList<Integer>对象
		ArrayList<Integer> array = new ArrayList<Integer>() ;
		//获取该对象的字节码文件对象
		Class clazz = array.getClass() ;
		//获取成员方法：public boolean add(E e)
		Method addMethod = clazz.getDeclaredMethod("add", Object.class) ;
		//调用该方法，向集合中添加字符串元素
		addMethod.invoke(array, "北京") ;
		addMethod.invoke(array, "上海") ;
		addMethod.invoke(array, "深圳") ;
		addMethod.invoke(array, "天津") ;
		addMethod.invoke(array, "广州") ;
		System.out.println(array);
	}
	
	

}
